CloudFormation テンプレートが肥大化したので分割する方法を教えてください
困っていた内容
CloudFormation でインフラ環境を構築していますが、テンプレートが非常に大きくなりました。可読性を高めるためにテンプレートファイルを分割したいのですが、分割する方法を教えてください。 なお、単純にファイルを分割するのではなく、一回の実行で複数のテンプレートがリリースされるようにしたいです。
どう対応すればいいの?
ネスト機能をお使いください。
ネストされたスタックの操作 - AWS CloudFormation
CloudFormation のネスト機能を使用することで、複数のテンプレートを一度に実行できます。具体的には、テンプレート内でAWS::CloudFormation::Stack
タイプのリソースとして別のテンプレート(S3 URL)を定義すると、実行時に指定したテンプレートも実行されます。
# 例 Resources: networkStack: Type: AWS::CloudFormation::Stack Properties: TemplateURL: <呼び出すテンプレートURL>
やってみた
先日使用した ECS タスクの停止理由を CloudWatch Logs に保管するテンプレートを使用します。
テンプレートでは、 EventBridge と CloudWatch Logs を作成しますが、EventBridge 部分を別ファイルに分割します。
- メインテンプレート(CloudWatch Logs):
ecs-stopped-tasks-cwlogs.yml
- サブテンプレート(EventBridge):
ecs-stopped-tasks-cwlogs_eventrule.yml
元ファイル
AWSTemplateFormatVersion: 2010-09-09 Description: Deploys the resources needed to store events of Amazon ECS stopped tasks in CloudWatch Logs Parameters: CWLogGroupName: Type: String Description: The CloudWatch log group name to store the events Default: /aws/events/ECSStoppedTasksEvent CWLogGroupRetention: Type: Number Description: The number of days to retain the events in the log group Default: 30 Resources: EventRule: Type: AWS::Events::Rule Properties: Name: ECSStoppedTasksEvent Description: Triggered when an Amazon ECS Task is stopped EventPattern: source: - aws.ecs detail-type: - ECS Task State Change detail: desiredStatus: - STOPPED lastStatus: - STOPPED State: ENABLED Targets: - Arn: !GetAtt LogGroup.Arn Id: ECSStoppedTasks LogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Ref CWLogGroupName RetentionInDays: !Ref CWLogGroupRetention
分割後
メインテンプレート
AWSTemplateFormatVersion: 2010-09-09 Description: Deploys the resources needed to store events of Amazon ECS stopped tasks in CloudWatch Logs Parameters: CWLogGroupName: Type: String Description: The CloudWatch log group name to store the events Default: /aws/events/ECSStoppedTasksEvent CWLogGroupRetention: Type: Number Description: The number of days to retain the events in the log group Default: 30 EventRuleTemplateURL: Type: String Description: Template URL for EventRule Resources: EventRule: Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Ref EventRuleTemplateURL Parameters: CWLogGroupARN: !GetAtt LogGroup.Arn LogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Ref CWLogGroupName RetentionInDays: !Ref CWLogGroupRetention
サブテンプレート
AWSTemplateFormatVersion: 2010-09-09 Description: Deploys the resources needed to store events of Amazon ECS stopped tasks in CloudWatch Logs Parameters: CWLogGroupARN: Type: String Resources: EventRule: Type: AWS::Events::Rule Properties: Name: ECSStoppedTasksEvent Description: Triggered when an Amazon ECS Task is stopped EventPattern: source: - aws.ecs detail-type: - ECS Task State Change detail: desiredStatus: - STOPPED lastStatus: - STOPPED State: ENABLED Targets: - Arn: !Ref CWLogGroupARN Id: ECSStoppedTasks
TemplateURLについて
分割したテンプレートは、あらかじめ S3 にアップロードしておく必要があり、アップロード先のURLを元テンプレートに記載する必要があります。
今回はテンプレート内ではなく、スタック作成時にパラメーターとしてテンプレートURLを指定します。
テンプレートアップロードとデプロイ
テンプレートファイルを S3 にアップロードします。
アップロードしたテンプレート(メイン・サブ)のURLをメモします。
AWS CloudFormation コンソールを開き、「スタックの作成」をクリックします。
「Amazon S3 URL」を選択し、「Amazon S3 URL」にメインテンプレートのURL(https://XXX.s3.ap-northeast-1.amazonaws.com/cf-templates/ecs-stopped-tasks-cwlogs.yml
)を入力。「次へ」をクリックします。
任意の名前を入力し、「EventRuleTemplateURL」にサブテンプレートのURL(https://XXX.s3.ap-northeast-1.amazonaws.com/cf-templates/ecs-stopped-tasks-cwlogs_eventrule.yml
)を指定します。
必要に応じてログの保管先(CloudWatch Logs のロググループ名)と保持期間(単位:日)を変更します。
次の項目にチェックを入れ、「スタックの作成」をクリックします。
- AWS CloudFormation によって IAM リソースがカスタム名で作成される場合があることを承認します。
- AWS CloudFormation によって、次の機能が要求される場合があることを承認します: CAPABILITY_AUTO_EXPAND
ステータスが「CREATE_COMPLETE」なったことを確認します。
ネスト関係のスタック表記
サブテンプレートには「ネストされた」と表記されます。 また「概要」欄にメインテンプレートが記載されます。
ネスト関係のスタック削除
ネストを使用したスタックを削除する場合はメインテンプレート側から削除を実行してください。
サブテンプレートだけも削除されますが、非推奨となります。(削除時に警告が表示されます)